package dev.ece.suit.hexmap.terrain;

import java.awt.Color;
import java.awt.image.BufferedImage;

import dev.ece.core.light.Material;
import dev.ece.suit.hexmap.MapCellCreator;
import dev.ece.suit.hexmap.HexMapCellShader;
import dev.ece.suit.hexmap.Terrain;
import dev.ece.suit.hexmap.TerrainModelCreator;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;

public class HeightMapTerrain implements Terrain {

	private int textureIndex;
	
	private Material material;
	
	private BufferedImage heightmap;
	
	private boolean enable;
	
	private int alphaIndex;
	
	private int blendIndex;
	
	public HeightMapTerrain(BufferedImage heightmap, int textureIndex) {
		this(heightmap, textureIndex, new Material(), -1, -1);
		setDefaultMaterial();
	}
	
	public HeightMapTerrain(BufferedImage heightmap, int textureIndex, int alphaIndex, int blendIndex) {
		this(heightmap, textureIndex, new Material(), alphaIndex, blendIndex);
		setDefaultMaterial();
	}
	
	public HeightMapTerrain(BufferedImage heightmap, int textureIndex, Material material, int alphaIndex, int blendIndex) {
		this.heightmap = heightmap;
		this.textureIndex = textureIndex;
		this.material = material;
		this.alphaIndex = alphaIndex;
		this.blendIndex = blendIndex;
		this.enable = alphaIndex > -1 && blendIndex > -1;
	}
	
	protected void setDefaultMaterial() {
		getMaterial().getDiffuse().set(0.5f, 0.5f, 0.5f);
		getMaterial().getSpecular().set(0f, 0f, 0f);
		getMaterial().setShininess(128);
	}
	
	@Override
	public float height(MapCellCreator cellCreator, Vector3f vertex, Vector2f uv) {
		int x =(int) ((heightmap.getWidth() - 1) * uv.getX());
		int y = (int) ((heightmap.getHeight() - 1) * uv.getY());
		Color color = new Color(heightmap.getRGB(x, y));
		return  color.getRed() * cellCreator.getCellOutSize() / 255f;
	}
	
	@Override
	public void glCellShader(HexMapCellShader cellShader, TerrainModelCreator terrainFactory) {
		cellShader.glTexture(texture(terrainFactory));
		cellShader.glMaterial(getMaterial());
		cellShader.glEnable(isEnable());
		if(isEnable()) {
			cellShader.glTexture(
					terrainFactory.getTextures()[alphaIndex], 
					terrainFactory.getTextures()[blendIndex]);
		}
	}

	public boolean isEnable() {
		return enable;
	}

	@Override
	public Material getMaterial() {
		return material;
	}

	@Override
	public int getTextureIndex() {
		return textureIndex;
	}

	@Override
	public boolean hasWater() {
		return false;
	}

}
